﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Platform.Storage.Redis
{
	public sealed class RedisKeysCommands : RedisCommandsBase
	{
		internal RedisKeysCommands( RedisMessageChannel channel )
			: base( channel )
		{ }

		public void Expire( string key, TimeSpan expire )
		{
			this.ErrorIf( this.Channel.ExecuteInt32( "EXPIRE", key, Convert.ToString( ( long )expire.TotalSeconds ) ) == 0 );
		}

		public bool Exists( string key )
		{
			return this.Channel.ExecuteInt32( "EXISTS", key ) == 1;
		}

		public void Set( string key, string value )
		{
			this.Channel.ExecuteSingle( "SET", key, value );
		}

		public void Set( string key, string value, TimeSpan expireAt )
		{
			this.Channel.ExecuteSingle( "SETEX", key, Convert.ToString( ( long )expireAt.TotalSeconds ), value );
		}

		public bool SetIfNotExists( string key, string value )
		{
			return this.Channel.ExecuteInt32( "SETNX", key, value ) == 1;
		}

		public string Get( string key )
		{
			return this.Channel.ExecuteSingle( "GET", key );
		}

		public IEnumerable<string> Get( params string[] keys )
		{
			return this.Channel.ExecuteOrQuery( "MGET", keys );
		}

		public IEnumerable<string> FindKeys( string pattern )
		{
			return this.Channel.ExecuteOrQuery( "KEYS", pattern );
		}

		public int Increment( string key )
		{
			return this.Channel.ExecuteInt32( "INCR", key );
		}

		public int Increment( string key, int step )
		{
			return this.Channel.ExecuteInt32( "INCRBY", key, step.ToString() );
		}

		public int Decrement( string key )
		{
			return this.Channel.ExecuteInt32( "DECR", key );
		}

		public int Decrement( string key, int step )
		{
			return this.Channel.ExecuteInt32( "DECRBY", key, step.ToString() );
		}

		public int Delete( params string[] keys )
		{
			if ( keys != null && keys.Length > 0 )
				return this.Channel.ExecuteInt32( "DEL", keys );
			else
				return 0;
		}

		public string TypeOf( string key )
		{
			return this.Channel.ExecuteSingle( "TYPE", key );
		}
	}
}
